{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "ea9e7d84-525a-4ad9-aba1-2d08b0f8c955",
   "metadata": {},
   "source": [
    "# A Closed Form Solution for Pricing Options: The Black-Scholes Model"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "65d11d15-a999-451e-b032-59ff9c946960",
   "metadata": {},
   "source": [
    "## Load the Libs we need"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6e45d955-fe61-42d1-b12c-b8491e2c366b",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "95f0ab3a-bc41-41f1-8ce8-70470117ba8e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# import Lib\n",
    "import pandas as pd\n",
    "import datetime as dt\n",
    "import pytz\n",
    "import os\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import yfinance as yf\n",
    "import numpy as np\n",
    "import scipy.stats as si\n",
    "\n",
    "# import module\n",
    "from datetime import datetime, timezone\n",
    "from datetime import date, time\n",
    "from math import trunc\n",
    "from dateutil.parser import parse\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ebb86b05-7c71-4cd1-8dd9-00609e6435cd",
   "metadata": {},
   "source": [
    "## Black-Scholes Pricing for Calls and Puts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "7de50c6d-0564-416c-951a-1ea0e2a21441",
   "metadata": {},
   "outputs": [],
   "source": [
    "# mb_black_scholes function needs the following variables:\n",
    "# S: spot price\n",
    "# K: strike price\n",
    "# T: time to maturity\n",
    "# r: interest rate\n",
    "# v: volatility of underlying asset\n",
    "\n",
    "def mb_black_scholes(S, K, T, r, v, option = 'call'):\n",
    "    d1 = (np.log(S / K) + (r + 0.5 * v ** 2) * T) / (v * np.sqrt(T))\n",
    "    d2 = (np.log(S / K) + (r - 0.5 * v ** 2) * T) / (v * np.sqrt(T))\n",
    "    if option == 'call':\n",
    "        result = (S * si.norm.cdf(d1, 0.0, 1.0) - K * np.exp(-r * T) * si.norm.cdf(d2, 0.0, 1.0))\n",
    "    if option == 'put':\n",
    "        result = (K * np.exp(-r * T) * si.norm.cdf(-d2, 0.0, 1.0) - S * si.norm.cdf(-d1, 0.0, 1.0))\n",
    "    return result"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "450bc7f2-aaaa-4dbb-ad58-547a7fae6533",
   "metadata": {},
   "source": [
    "#### Let's price a call and a put"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "000bbc34-c61e-4459-9cc6-bd78634da5c9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The Black-Scholes price of the call option is: 45.037061545347896\n",
      "The Black-Scholes price of the put option is: 7.965328097951435\n"
     ]
    }
   ],
   "source": [
    "call_price = mb_black_scholes(175, 145, 1, 0.05, 0.35, option = 'call')\n",
    "put_price = mb_black_scholes(175, 145, 1, 0.05, 0.35, option = 'put')\n",
    "\n",
    "print(f\"The Black-Scholes price of the call option is: {call_price}\")\n",
    "print(f\"The Black-Scholes price of the put option is: {put_price}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a35e8ad4-f2fe-412a-98c5-c5d467ccb3b8",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "37402855-4e51-4cd5-a4d8-558939a707ae",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "           contractSymbol              lastTradeDate  strike  lastPrice  \\\n",
      "0     AAPL230526C00095000  2023-05-19 19:36:18+00:00    95.0      80.27   \n",
      "1     AAPL230526C00100000  2023-05-17 13:59:34+00:00   100.0      75.32   \n",
      "2     AAPL230526C00110000  2023-05-16 18:17:19+00:00   110.0      62.18   \n",
      "3     AAPL230526C00115000  2023-05-08 15:00:05+00:00   115.0      58.70   \n",
      "4     AAPL230526C00120000  2023-05-17 19:25:47+00:00   120.0      52.52   \n",
      "...                   ...                        ...     ...        ...   \n",
      "1628  AAPL251219P00260000  2023-05-15 18:24:01+00:00   260.0      86.91   \n",
      "1629  AAPL251219P00270000  2023-05-05 14:01:40+00:00   270.0      96.76   \n",
      "1630  AAPL251219P00290000  2023-05-11 17:03:36+00:00   290.0     116.36   \n",
      "1631  AAPL251219P00300000  2023-04-19 13:31:50+00:00   300.0     134.00   \n",
      "1632  AAPL251219P00310000  2023-05-15 18:24:01+00:00   310.0     139.21   \n",
      "\n",
      "         bid     ask    change  percentChange  volume  openInterest  \\\n",
      "0      78.95   81.45  1.269997       1.607591     7.0             0   \n",
      "1      73.50   76.50  4.639999       6.564798     1.0             6   \n",
      "2      63.50   66.55  0.000000       0.000000    13.0            13   \n",
      "3      59.10   61.55  0.000000       0.000000     1.0             3   \n",
      "4      53.60   56.95  0.000000       0.000000     6.0             5   \n",
      "...      ...     ...       ...            ...     ...           ...   \n",
      "1628   82.75   86.65  0.000000       0.000000    86.0             0   \n",
      "1629   92.75   96.65  0.000000       0.000000     1.0             0   \n",
      "1630  112.70  116.60  0.000000       0.000000    20.0             0   \n",
      "1631    0.00    0.00  0.000000       0.000000     1.0             0   \n",
      "1632  132.70  136.60  0.000000       0.000000    93.0             0   \n",
      "\n",
      "      impliedVolatility  inTheMoney contractSize currency OptionType  \\\n",
      "0              1.812501        True      REGULAR      USD       Call   \n",
      "1              2.871097        True      REGULAR      USD       Call   \n",
      "2              2.478519        True      REGULAR      USD       Call   \n",
      "3              1.539065        True      REGULAR      USD       Call   \n",
      "4              1.332035        True      REGULAR      USD       Call   \n",
      "...                 ...         ...          ...      ...        ...   \n",
      "1628           0.168923        True      REGULAR      USD        Put   \n",
      "1629           0.180520        True      REGULAR      USD        Put   \n",
      "1630           0.200753        True      REGULAR      USD        Put   \n",
      "1631           0.000010        True      REGULAR      USD        Put   \n",
      "1632           0.220070        True      REGULAR      USD        Put   \n",
      "\n",
      "     expirationDate  time_to_expiration  \n",
      "0        2023-05-26                   4  \n",
      "1        2023-05-26                   4  \n",
      "2        2023-05-26                   4  \n",
      "3        2023-05-26                   4  \n",
      "4        2023-05-26                   4  \n",
      "...             ...                 ...  \n",
      "1628     2025-12-19                 942  \n",
      "1629     2025-12-19                 942  \n",
      "1630     2025-12-19                 942  \n",
      "1631     2025-12-19                 942  \n",
      "1632     2025-12-19                 942  \n",
      "\n",
      "[1633 rows x 17 columns]\n"
     ]
    }
   ],
   "source": [
    "mb_src_prices = pd.read_csv(\"mb_tickerDf05192023 2023-05-21 11-06-44-380372.csv\", index_col=0)\n",
    "mb_src_options = pd.read_csv(\"mb_all_options_data05192023 2023-05-21 11-06-51-071892.csv\", index_col=0)\n",
    "mb_src_ir = pd.read_csv(\"mb_US_T_05192023 2023-05-21 11-06-56-696354.csv\", index_col=0)\n",
    "\n",
    "# Parsing the dates in the index and convert them to date only (without time or timezone info)\n",
    "mb_src_prices.index = mb_src_prices.index.map(lambda x: parse(x).date())\n",
    "\n",
    "#print(mb_src_prices)\n",
    "print(mb_src_options)\n",
    "#print(mb_src_ir)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "bf3331ea-69af-4375-b3de-067fa572be7c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "           contractSymbol              lastTradeDate  strike  lastPrice  \\\n",
      "1094  AAPL240621C00145000  2023-05-19 19:56:33+00:00   145.0      42.70   \n",
      "1146  AAPL240621P00145000  2023-05-19 15:15:17+00:00   145.0       6.53   \n",
      "\n",
      "        bid   ask    change  percentChange  volume  openInterest  \\\n",
      "1094  43.20  44.2 -0.099998      -0.233641     1.0          3485   \n",
      "1146   6.15   7.0 -0.290000      -4.252199   216.0          8781   \n",
      "\n",
      "      impliedVolatility  inTheMoney contractSize currency OptionType  \\\n",
      "1094           0.400214        True      REGULAR      USD       Call   \n",
      "1146           0.275550       False      REGULAR      USD        Put   \n",
      "\n",
      "     expirationDate  time_to_expiration  \n",
      "1094     2024-06-21                 396  \n",
      "1146     2024-06-21                 396  \n"
     ]
    }
   ],
   "source": [
    "strike_target = 145\n",
    "expiration_target = 396\n",
    "\n",
    "row_target = mb_src_options.loc[(mb_src_options['strike'] == strike_target) & \n",
    "                                (mb_src_options['time_to_expiration'] == expiration_target)]\n",
    "\n",
    "print(row_target)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "53a7a0c2-04d2-4bd6-98f5-7b10256f1a23",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "64d40449-e24e-4886-8205-cc4ccf812a25",
   "metadata": {},
   "source": [
    "#### Spot Ladder"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "b728ba2f-4bf1-4871-8b8a-be925d9e9bb1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "    Spot Price  Call Price  Put Price\n",
      "0          100    0.619309  90.865194\n",
      "1          110    1.262418  81.508303\n",
      "2          120    2.299140  72.545025\n",
      "3          130    3.829395  64.075279\n",
      "4          140    5.935591  56.181476\n",
      "5          150    8.676300  48.922185\n",
      "6          160   12.084155  42.330040\n",
      "7          170   16.167140  36.413025\n",
      "8          180   20.912077  31.157962\n",
      "9          190   26.289185  26.535070\n",
      "10         200   32.256858  22.502743\n",
      "11         210   38.766076  19.011961\n",
      "12         220   45.764142  16.010027\n",
      "13         230   53.197635  13.443520\n",
      "14         240   61.014579  11.260464\n",
      "15         250   69.165935   9.411820\n",
      "16         260   77.606516   7.852401\n",
      "17         270   86.295460   6.541344\n",
      "18         280   95.196376   5.442261\n",
      "19         290  104.277257   4.523142\n",
      "20         300  113.510242   3.756127\n"
     ]
    }
   ],
   "source": [
    "# SPOT LADDER\n",
    "\n",
    "# Define parameters\n",
    "K = 200\n",
    "T = 1\n",
    "r = 0.05\n",
    "v = 0.35\n",
    "\n",
    "# Define range for spot price\n",
    "S_range = np.arange(100, 310, 10)\n",
    "\n",
    "# Calculate call and put prices for each spot price\n",
    "call_prices = [mb_black_scholes(S, K, T, r, v, option = 'call') for S in S_range]\n",
    "put_prices = [mb_black_scholes(S, K, T, r, v, option = 'put') for S in S_range]\n",
    "\n",
    "# Create DataFrame\n",
    "df = pd.DataFrame({\n",
    "    'Spot Price': S_range,\n",
    "    'Call Price': call_prices,\n",
    "    'Put Price': put_prices\n",
    "})\n",
    "\n",
    "print(df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "5644fc79-ad50-4e95-bd18-28ac5e82d400",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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KXv+eW/BNGiQapcVsNWr4aKL4KSToHx5+OIL6NsXSpSIOjIRSVRKyESSzd57w2OPwZQpcNBB3qy8dWsfnpG4GznSR8VefNFLWkyZAmlpUUclIolOCZlIsmrSJLOuwg8/eC2zM87wdkyS79auhcsu870We+3l3/oHH/RlfiIiO6OETCSZFSnidRXmzPFFTO+/77sxr7wSlmZbe1l2w7hxXlesf3+49lr49ls46qiooxKRwkQJmUgqKFfOFzHNmQMXXujtmA4+GO69F9atizq6Qmv9el+u16aN577jxsH//R+ULh11ZCJS2CghE0klVav6MM706dCunY+a1a3rGwBUv2yXTJzos8JPPglXXOGtj447LuqoRKSwUkImkooOPRTeeQcmTIBateCSS3zObdgw7cjciY0b4frrve/k5s0wejQ8/TSUKRN1ZCJSmCkhE0llxxzjq8+HDoX0dO+R2aqV12mQHXz1FTRtCo8+6kvzpk2Dtm2jjkpEkoESMpFUZwannebTmP37w+zZXlj29NPhp5+iji4hbNoEt97q35a1a+GTT+DZZ73CiIhIflBCJiKuWDH45z994f/dd3vW0aCB13JYsiTq6CLz7bdw5JFw//3eAun7772fu4hIflJCJiLbKlvW+2POmePtl55/3gvM3n23Dw+liM2b/ZKbN4fly+G992DAAK+8LyKS35SQiUj29tsP+vWDmTOhUye46y4vldG/v2crSez7772O7l13Qc+ePpt7yilRRyUiyUwJmYjkrm5db1o+aRIccghceqn3Bho6NOl2ZG7c6ElYs2bw229+iS+/DBUrRh2ZiCQ7JWQikjdHHeWVT4cP9/Vm3bpl7tJMAiNHeuWPu+/2/QwzZvheBxGRgqCETETyzgxOPdWroL7wAixY4AW5unaFWbOijm63/P479OrlPShDgE8/hSFDoFKlqCMTkVSihExEdl2xYt6CafZsuO8+r47asCGcc46vOSsE0tO9g9Shh8Jbb8Gdd/rasfbto45MRFKREjIR2X177QW33AJz58K//uWLrg47zKczp0yJOrocTZ0KRx/tFT2aNfMCr3fdBaVKRR2ZiKQqJWQisucqV/au2gsWeH/M0aMhLQ1OPBHGj486ur+tWQPXXutJ2Lx58MorvnasXr2oIxORVKeETETyT6VK0LevJ2YPPuhVVVu39q7bH30U2a7MEHzwrn59eOIJb935ww++dswskpBERLahhExE8l+5cnDjjTB/vnfeXrAATjrJh6beessXcBWQ+fOhc2efRa1UCSZO9LVjFSoUWAgiIjulhExE4qd0abjiCq/6P2AArFsH3bv7OrNBg+JaYHbzZnjoIe/+NGaMz6hOnuzVO0REEo0SMhGJvxIl4PzzfQfm669DyZJw3nledPaZZ7wiaz6aMAGaNoWbboKOHb0ix7XX+uZQEZFEpIRMRApO0aLQo4evLXv/fTjgALj8cqhdGx55xFfd74E//oCLLvIla2vWwLBh8M47UL16PsUvIhInSshEpOCZwckne5X/MWO8htkNN0DNml5/YsWKXXq6EGDgQK8pNmiQP9XMmb52TESkMFBCJiLRMYM2bbw8/pdfQqtW3ruoZk24/npYvHinTzFrlj/F+ed7q81vvvG1Y2XKxD16EZF8o4RMRBJD8+bw7rteLr9zZ3jsMZ/KvOwy3yq5nfXr4dZboXFj/5Lnn4fPPvPBNhGRwkYJmYgklsMPh8GD4aef4NxzvWfmwQdD795ePAz4+GM/7f774ayz4Mcffe1YEf2PJiKFlP77EpHEdNBB8Nxz8PPPcOWV8OabhAYN+OrA03i000hKlgiMGeNrxypXjjpYEZE9o4RMRBJbtWqsu/dxHrliAQ8VvZXaiyYwkvbMDPVpM+0p+PPPqCMUEdljSshEJGFt3er1ZOvWhRseqcw3p93DmpkL4eWXsYoVvKH5AQfAP//pHcJFRAopJWQikpBGjIAjjoALL/RNl59/Dm+8AXXql4Szz4ZJk2DKFOjZE156yVf3H3ccvPYa/PVX1OGLiOwSJWQiklBmzPC2lx06eHHX11/3/pNHH53NyUccAf/7H/z2Gzz6qJfJOPNMqFED7rgDFi4s8PhFRHaHEjIRSQhLlvjMY6NGPvj16KNeY6xHDy9XlquKFeG663xn5ocfQloa3Hsv1KrlXcVHj/bqsSIiCUoJmYhEav16z50OPtjXi115pfciv+46b3m5S4oUgU6dvC3T3Ln+JOPGQbt23tC8Xz9YvTou1yEisieUkIlIJNLTvc3RIYfA7bf7FOXMmfDEE7DvvvnwArVre8n+X3/12hhly3q2d+CBXmx2xox8eBERkfyhhExECtzo0dCsGZx3nm+SHD8e3n7bd1Pmu9KlvajsV1/5rVs3H4o7/HDvufTGG7B5cxxeWEQk75SQiUiBmTULTj3VZxBXroQhQ+CLL3xzZIE48kgfLfvtN3j4YfjlFzjjjMym5osWFVAgIiLbUkImInG3dKnPEjZs6KNhDz3kXZDOPDOidkf77uvNy2fP9vVmTZpA376emPXoAWPH+pyqiEgBUUImInGzYQM88IAv2H/uObj0Ul9rf8MNUKpU1NEBRYvCySf7zszZs73Q7MiR0LYt1KkDt932d/9MEZF4UkImIvkuPR1eeQXq1YNbboHjj/c19E8/DZUqRR1dDg46yGttLFzowR96qGeT9ev7VOeTT3ptDhGROFBCJiL5atw4aN4czjkHqlSBMWPg3Xc9OSsU9toLevWCjz/2tWaPPeY9nK6+2ndonnQSvPqq1+sQEcknSshEJF/8+CN07eobF5cuhZdf9k2NbdpEHNie2H9/uOYa+OYbmD7d151Nnw5nnQX77efbREeO9IRNRGQPFHhCZmbVzWyMmc0ysxlm9q/Y8YpmNsLMZsc+Vijo2ERk182eDeef73VXR4+G++/35OzssyNasB8vhx3mU5jz5/uw3xlnwDvvQPv23qrp+uvV4FxEdlsU/11uAa4LIdQHjgIuN7MGwE3AqBBCXWBU7HMRSVCzZnnSdeih3m8yo8L+zTd76a+kVaSID/u98AL8/rvXMWvWzCvaNm7st0ce8elOEZE8KvCELISwOITwTez+GmAWcCDQBRgUO20Q0LWgYxORnZs+HXr29AGjd97x7kTz5sHjj/uasZRSujR07w7Dh3sNs379/NgNN0D16nDCCd6OYM2aqCMVkQRnIcKGu2ZWCxgPHA78EkIon+WxlSGEHaYtzewS4BKAGjVqNFuwYEHBBCuS4qZOhXvugaFDM7sQXXMNVK4cdWQJaPZs36n5yivw88+epHXt6kOKHTpAsWJRRygiETCzKSGEtGwfiyohM7OywDjgvhDCUDNblZeELKu0tLQwefLkOEcqktomT/ZEbPhw2GcfL9X1r39BxYpRR1YIhACTJvkOh9df9/YEVar4EOM55/hUp1nUUYpIAcktIYtkya2ZFQfeBgaHEIbGDi8xs6qxx6sCS6OITUTcF194zdQjj4TPPvNC9vPnw913KxnLMzM4+mj4739h8WKf4z32WOjf37+xder4MOPYsbBlS9TRikiEothlacD/gFkhhMeyPDQc6B273xsYVtCxiQhMmOCzai1bwpdfZm4svP12KF8+6ugKsZIlfdry7bd9M8Dzz/tCvP/+1zsD7LefN0F/5x1Yty7qaEWkgBX4lKWZHQt8BnwPZDSLuwX4EngDqAH8AnQPIazI7bk0ZSmSP0Lwgq59+3pFhypVvIpDnz6+XkziaM0a+OQTGDbM+2quWuV9pdq39wTulFNScLeESHJKyDVk+UEJmcieCcHrmvbt6yNjVav6BsFLLvGC9VLANm/27uvDhnl7g19/9WnPY46BLl08QTv44KijFJHdpIRMRLYRgncG6tvX14pVqwY33QQXXpggTb/Ff0hTp3piNmwYfPedH2/QwBOzrl19U0BSVd8VSW5KyEQE8N/x773nuyYnT4aaNb2Q63nn+RInSWDz5nliNmyYj6Klp8MBB/jIWZcuvg6tRImooxSRXCghE0lx6ek+0HLPPT7oUqcO3HqrV14oXjzq6GSX/fEHfPCB/1A/+cQbnZcr543Pu3SBTp28RomIJBQlZCIpauNG7+zzyCNeYb9uXbjtNu+NrdqkSWLDBl8I+O67Pvy5bJln2W3bZm4KqF496ihFBCVkIinn11+9msLzz8Py5b7s6NZbvR920aJRRydxs3WrF6IdNszLZ8yd68fr1fM2Tiec4H04Vb9EJBJKyERSQAheX7RfPx8sAejcGa64Ao4/XgXhU04IMHOmT2mOHOl1Tdav900ARx6ZmaC1bKkFhCIFRAmZSBJbu9ZbJvbrBzNmwL77wsUXew2xmjWjjk4Sxl9/+ZbakSP99tVXPqJWujS0apWZoDVqpJ2bInGihEwkCf30EzzzDLz4IqxeDUcc4Q2/zzjDf8eK5OrPP33ULCNBmzXLj1euDO3aZSZoyupF8o0SMpEksXWr1w/r188/Fi8O3bt7ItaihaYlZQ/89huMGpWZoC1e7McPPjgzOWvbVo1MRfaAEjKRQm7lShgwwEfEfv7Zy0/16eNTk/vvH3V0knRC8BGzjORszBifGzfzYrQZCdoxx6iSsMguUEImUkh99x385z++RmzDBjjuOF+kf9ppqh8mBWjzZvj668wEbdIk2LLFk7Fjj/UpzmOP9WRN8+UiOVJCJlKIbN7sFQv69YPPPvPfb2efDZdfDo0bRx2dCN4Q/bPPMhO077/348WL+2LGo4/2W8uWcOCB0cYqkkCUkIkUAr//7nXD+veHRYugdm1Pwi64ACpUiDo6kVwsW+ajZpMmwcSJvoNz40Z/rEaNzATt6KN9F6eGdyVFKSETSVAheCWCfv3gzTd9dKxjR1+kf+KJKuIqhdRff/l8+8SJmbeFC/2xvfaC5s0zE7SjjvJaLSIpQAmZSIJZuBBeew0GD/bekuXKwfnnw2WXwSGHRB2dSBz8+mvmCNrEifDtt74ODbyTQNZRtEMPVS00SUpKyEQSwMqV8NZbMGSIl38KwQcKzjvPm3yXLRt1hCIFaP16mDw5M0GbNMn7fIG3dmrZMjNBa95cbxBJCkrIRCKyYYP3ex4yBD780KckDzkEevWCM8/0Zt8igv+FMmfOttOcM2b48SJFfO3ZkUdC06Z+a9TIpz9FChElZCIFaMsWr685ZAgMHerlm6pW9QTsrLN8E5oKuIrkwapV8OWXmSNoU6bAihX+WJEiPtWZkaBl3FS4VhKYEjKROAvBf28MGQKvvw5Ll8I++8Dpp3sS1rq1FuiL7LEQfC3at99ue/v118xzatTYMUmrVk1/BUlCyC0hK1bQwYgkk1mzPAkbMsQr6JcsCaee6knYSSf55yKST8w84apRA7p0yTy+fLnvjsmapA0f7gkc+C7OJk22TdIOOUR/JUlC0QiZyC7K2CE5ZIj/v1+kiBcqP+ssr6C/zz5RRygirFsH06bBN99kJmnTp3tJDvD1Z40abZukHX64WkFJXGnKUmQPrVgBb7+94w7Js86CM85QP0mRQmHzZpg5c9uRtKlTvfMAQLFivi6tQQOoXz/z4yGHKFGTfKGETGQ3rF8P77+f/Q7Js86Cgw+OOkIR2WPp6b7eICNB+/57X4vw88+ZU55FikCdOtsmaRm3vfeONn4pVJSQieTRL7/Axx/DRx95i761a+GAA6BnT0/EmjbV2mCRlLBhA/z0kydnM2f6x1mz/NjmzZnnVau2Y6LWoAFUqhRd7JKwtKhfJAebNnmP5IwkbOZMP16jhidgZ5wBrVpp7a9IyildGho39ltWmzf76Nn2idrzz/uweoZKlbJP1A48UH/VSbY0QiYpZ948T74+/hhGj/a1vyVKeGmKE0+ETp28c4v+zxSRPEtP9/IbGQlaRrI2c6a36ciw997+H8zBB8NBB/lU6EEH+a1qVbWMSnKaspSUtmEDjB/vSdhHH/mMA/j/g506eRLWti2UKRNtnCKShELwwoRZE7UffoC5c2HBAk/kMpQqBbVrZyZoWRO22rVVRycJaMpSUs7s2ZnTkGPHelJWqhS0aQOXX+5JWN26GgUTkTgzg/3281ubNts+tnmzJ2U//+wJWsbt559hzBgfvs/6PNWqbTuiljVpU4eCQk8JmSSF9es98coYBZs714/XrQsXX+wjYa1b+7IQEZGEULy4T11mt2U7Y2Qta5KWcf+DD2DJkm3PL19+x1G1WrWgenW/qe9nwlNCJoVSCPDjj5mjYOPG+QL9vfaC44+Ha67xUbCDDoo6UhGR3ZB1ZO3oo3d8fN26bZO0jPvffONNdLds2fb8ihU9MatRIzNJy3o78EBfTCuRUUImhcLWrTBjBnzxhd/GjIH58/2x+vUzpyGPO071G0UkBZQpAw0b+m17W7b4BoNffvGPWe8vWAATJmy70QA8Adx//+yTtYwkbr/9tOU8jpSQSUL6/Xdv1p2RgH39deZyikqV4Jhj4KaboGNHH5UXEZGYYsV8E0Dt2jmfs3at94HLmrRl3GbM8OmHrGvYMp73wAO3TdaqVfPdoVWrekK3//7aIbWbtMtSIrdpkxfIzki+vvwyc/SrWDEvxnrUUZm32rW1GF9EJK5C8FG07ZO1rCNuCxduWyQ3w957ZyZnWRO17e9XqpRyI27aZSkJIwRPtjKSry++8FZyGf1+a9TwpOuqq6BFC0/GtBBfRKSAmfm6s4oVdyyOmyE9HZYt8w0Gixf71EbGx4z7U6f6/dWrd/z6IkWgSpXck7aso25J/pe4EjKJqzVrfLoxY+Triy984xD4Avy0NLj6ak/CWrTwNkUiIlIIFCmSufGgUaPcz123zhO37JK2jPvffefnbN2649eXKgWVK/uoWqVKO7+/774+xVKIFK5oJaFt3OhFV7/+OjP5mj49sz9vvXpefiJj6vHwwwvd+0VERHZHmTJejqNOndzPS0+H5ct3TNiWL/fRuOXL/TZ3rn/MbuQtQ4UKuSdt2x/be+9IR+H061B22cqVXnD6hx+2/ThvXmbR6fLlPenq1s1Hvpo3V91CERHZiYxpzCpVdj7qBr7eJSNJ2z5py3p//nyYPNmPZbfuDXyX2Mcf5+vl7AolZJKtEHy9Zka3j6zJV9Z6hCVLwiGHwBFHeDPuQw/1+3XrqiWbiIjEWYkSvtYlr+tdQvC1NNklbRGvmVFCluL++gvmzMlMuDKSrh9+2HbHc/nyXu/r5JM96apf32+1aqXcJhkRESmszKBcOb/tbPq0gCkhSwHp6b6QfsGCzGQrI/maO3fb9ZM1anjCddFFmYnXoYf66HGSb3ARERGJjBKyQm7TJli0yKcXf/st82PW+4sWbdtFo3hxn1Js2BC6d88c7TrkEChbNrprERERSVVKyBLY6tU7Jlrbf1y2bMevK1vWiylXqwZt2vjHjOLK9er5KK12N4qIiCQO/VouQBs3+g7FlSthxYrM+ytX+pTi9gnX2rU7PkflypnJVosWmclW1o/lyhX8tYmIiMjuS7iEzMxOBJ4EigIvhBAejDikbWzYsG0itSu3jRtzft5ixbwocbVqXp/rxBN3TLQOOMB3NYqIiEhySaiEzMyKAv8B2gMLga/NbHgIYWYU8axcCaeeuu2o1qZNuX/NPvt4LbqMW/36236e0618ee1WFBERSVUJlZABzYE5IYSfAczsNaALEElCVrq0j0gpqRIREZF4SrSE7EDg1yyfLwRaRBQLpUrBqFFRvbqIiIikikSrpZ5dpauwzQlml5jZZDObvCy7LYYiIiIihUyiJWQLgepZPq8GLMp6QgjhuRBCWgghrXLlygUanIiIiEg8JFpC9jVQ18xqm1kJoCcwPOKYREREROIqodaQhRC2mNkVwCd42YsBIYQZEYclIiIiElcJlZABhBA+BD6MOg4RERGRgpJoU5YiIiIiKUcJmYiIiEjElJCJiIiIREwJmYiIiEjElJCJiIiIREwJmYiIiEjElJCJiIiIREwJmYiIiEjELISw87MSlJktAxYUwEtVApYXwOskolS+dkjt69e1p65Uvv5UvnZI7esviGuvGULIthF3oU7ICoqZTQ4hpEUdRxRS+dohta9f156a1w6pff2pfO2Q2tcf9bVrylJEREQkYkrIRERERCKmhCxvnos6gAil8rVDal+/rj11pfL1p/K1Q2pff6TXrjVkIiIiIhHTCJmIiIhIxFI+ITOzAWa21MymZzlW0cxGmNns2McKWR672czmmNmPZtYxmqjzTw7X/4iZ/WBm08zsHTMrHztey8w2mNnU2K1/ZIHngxyu/S4z+y3LNZ6U5bGk+dnncO2vZ7nu+WY2NXY8qX7uAGZW3czGmNksM5thZv+KHU/6934u15707/tcrj1V3vc5XX/Sv/fNrJSZfWVm38Wu/e7Y8cR5z4cQUvoGtAKOAKZnOfYwcFPs/k3AQ7H7DYDvgJJAbWAuUDTqa4jD9XcAisXuP5Tl+mtlPa+w33K49ruAf2dzblL97LO79u0e/z/gjmT8uceuqSpwROz+3sBPsZ9x0r/3c7n2pH/f53LtqfK+z/b6tzsnKd/7gAFlY/eLA18CRyXSez7lR8hCCOOBFdsd7gIMit0fBHTNcvy1EMKmEMI8YA7QvCDijJfsrj+E8GkIYUvs0y+AagUeWAHI4Wefk6T62ed27WZmQA/g1QINqgCFEBaHEL6J3V8DzAIOJAXe+zldeyq873P5ueckaX7usPPrT+b3fnBrY58Wj90CCfSeT/mELAf7hRAWg/8DBqrEjh8I/JrlvIXk/mZOBhcAH2X5vLaZfWtm48zsuKiCirMrYtM2A7IMX6fSz/44YEkIYXaWY0n7czezWkBT/C/mlHrvb3ftWSX9+z6ba0+p930OP/ukfu+bWdHYdOxSYEQIIaHe80rIdo1lcyxpt6ma2a3AFmBw7NBioEYIoSlwLTDEzMpFFV+c/Bc4CGiCX+//xY6n0s/+TLb9Czlpf+5mVhZ4G7g6hLA6t1OzOVaof/45XXsqvO+zufaUet/n8u8+qd/7IYStIYQm+OhvczM7PJfTC/xnr4Qse0vMrCpA7OPS2PGFQPUs51UDFhVwbAXCzHoDpwC9QmxCPTZ0+0fs/hR8Tv2Q6KLMfyGEJbE3bTrwPJlD1CnxszezYsA/gNczjiXrz93MiuO/lAaHEIbGDqfEez+Ha0+J9312155K7/tcfvYp894PIawCxgInkkDveSVk2RsO9I7d7w0My3K8p5mVNLPaQF3gqwjiiyszOxG4EegcQlif5XhlMysau18Hv/6fo4kyPjLemDGnARm7EFPiZw+cAPwQQliYcSAZf+6xtTL/A2aFEB7L8lDSv/dzuvZUeN/ncu0p8b7P5d89JPl7P3Yt5WP3SxO7XhLpPR/PHQOF4YYPzy4GNuMZ8YXAvsAoYHbsY8Us59+K/5XwI9Ap6vjjdP1z8LnzqbFb/9i53YAZ+M6Tb4BTo44/Dtf+MvA9MA1/Q1ZNxp99dtceOz4Q6LPduUn1c49d07H49MO0LP/OT0qF934u15707/tcrj1V3vfZXn/ssaR+7wONgG9j1z6dzJ2kCfOeV6V+ERERkYhpylJEREQkYkrIRERERCKmhExEREQkYkrIRERERCKmhExEREQkYkrIRKTQMbNbzWxGrNXNVDNrsZvP09XMGuTw2F1m9lvs+aebWecczutjZufuzuuLiGQoFnUAIiK7wsxa4tXkjwghbDKzSkCJ3Xy6rsD7wMwcHn88hPComdUHPjOzKsGruWfEUiyE0H83X1tE5G9KyESksKkKLA8hbAIIISzPeMDM5uOtX9rGDp0VQphjZjWBAUBlYBlwPt4KpTPQ2sxuA7qFEOZm94IhhFlmtgWoZGZvABOBY4DhZrY3sDaWuB0M9I+9zlagewhhrpldD/QASgLvhBDuzMfvh4gkAU1Zikhh8ylQ3cx+MrNnzKz1do+vDiE0B/oBT8SO9QNeCiE0wptmPxVCmIhXZb8+hNAkp2QMIDYlmo4ncwDlQwitQwj/t92pg4H/hBAaA0cDi82sA952pTnevLqZmbXarSsXkaSlhExECpUQwlqgGXAJniC9bmbnZTnl1SwfW8butwSGxO6/jLeQyYtrzGwq8ChwRshsbfL69ifGRsoODCG8E4tzY/CekB1it2/x9jOH4gmaiMjfNGUpIoVOCGErMBYYa2bf402BB2Y8nPXUnJ4ijy/1eAjh0WyOr8vmmOXwHAY8EEJ4No+vKSIpSCNkIlKomFk9M8s6wtQEWJDl8zOyfJwUuz8R6Bm73wuYELu/Btg7P+IKIawGFppZ11icJc1sL+AT4AIzKxs7fqCZVcmP1xSR5KERMhEpbMoCT5tZeWALMAefvsxQ0sy+xP/gPDN27CpgQGxxfcaifoDXgOfN7Crg9NzWkeXROcCzZtYX2Iwv6v80tktzkpkBrAXOBpbu4WuJSBKxzCURIiKFW2yXZVrWnZciIoWBpixFREREIqYRMhEREZGIaYRMREREJGJKyEREREQipoRMREREJGJKyEREREQipoRMREREJGJKyEREREQi9v+LopURk0AmEQAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 720x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Set plot size and title\n",
    "plt.figure(figsize=(10, 6))\n",
    "plt.title('Black-Scholes Option Pricing')\n",
    "\n",
    "# Plot call and put prices\n",
    "plt.plot(df['Spot Price'], df['Call Price'], label='Call Prices', color='blue')\n",
    "plt.plot(df['Spot Price'], df['Put Price'], label='Put Prices', color='red')\n",
    "\n",
    "# Set labels and legend\n",
    "plt.xlabel('Spot Price')\n",
    "plt.ylabel('Option Price')\n",
    "plt.legend()\n",
    "\n",
    "# Display plot\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f047231f-b5c2-484c-811a-2cee78bcd68d",
   "metadata": {},
   "source": [
    "## Decoding the Greeks"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "40758ed4-f10d-4869-8a23-2b7672f2b56b",
   "metadata": {},
   "source": [
    "###### First, let's use the analytical approach, based on the closed-form solution of the Black-Scholes model. \n",
    "###### These are the Python functions to calculate the Greeks:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "3b21fbc2-5ac1-4b57-8bcd-6c73088930d8",
   "metadata": {},
   "outputs": [],
   "source": [
    "def mb_bs_delta(S, K, T, r, v, option='call'):\n",
    "    d1 = (np.log(S / K) + (r + 0.5 * v ** 2) * T) / (v * np.sqrt(T))\n",
    "    if option == 'call':\n",
    "        delta = si.norm.cdf(d1, 0.0, 1.0)\n",
    "    elif option == 'put':\n",
    "        delta = si.norm.cdf(d1, 0.0, 1.0) - 1\n",
    "    return delta\n",
    "\n",
    "def mb_bs_gamma(S, K, T, r, v):\n",
    "    d1 = (np.log(S / K) + (r + 0.5 * v ** 2) * T) / (v * np.sqrt(T))\n",
    "    gamma = si.norm.pdf(d1, 0.0, 1.0) / (S * v * np.sqrt(T))\n",
    "    return gamma\n",
    "\n",
    "def mb_bs_theta(S, K, T, r, v, option='call'):\n",
    "    d1 = (np.log(S / K) + (r + 0.5 * v ** 2) * T) / (v * np.sqrt(T))\n",
    "    d2 = d1 - v * np.sqrt(T)\n",
    "    if option == 'call':\n",
    "        theta = -(S * si.norm.pdf(d1, 0.0, 1.0) * v / (2 * np.sqrt(T))) - r * K * np.exp(-r * T) * si.norm.cdf(d2, 0.0, 1.0)\n",
    "    elif option == 'put':\n",
    "        theta = -(S * si.norm.pdf(d1, 0.0, 1.0) * v / (2 * np.sqrt(T))) + r * K * np.exp(-r * T) * si.norm.cdf(-d2, 0.0, 1.0)\n",
    "    return theta\n",
    "\n",
    "def mb_bs_vega(S, K, T, r, v):\n",
    "    d1 = (np.log(S / K) + (r + 0.5 * v ** 2) * T) / (v * np.sqrt(T))\n",
    "    vega = S * si.norm.pdf(d1, 0.0, 1.0) * np.sqrt(T)\n",
    "    return vega\n",
    "\n",
    "def mb_bs_rho(S, K, T, r, v, option='call'):\n",
    "    d2 = (np.log(S / K) + (r - 0.5 * v ** 2) * T) / (v * np.sqrt(T))\n",
    "    if option == 'call':\n",
    "        rho = K * T * np.exp(-r * T) * si.norm.cdf(d2, 0.0, 1.0)\n",
    "    elif option == 'put':\n",
    "        rho = -K * T * np.exp(-r * T) * si.norm.cdf(-d2, 0.0, 1.0)\n",
    "    return rho\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "22733a82-e2d8-4eb0-a5c2-72dd21fc4e72",
   "metadata": {},
   "source": [
    "###### For the numerical approach, we use the concept of finite differences. \n",
    "###### Here, the Greeks are approximated by perturbing each parameter slightly and seeing how much the option price changes:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "11cff06b-f7ff-42ca-bc25-e77cb4206afe",
   "metadata": {},
   "outputs": [],
   "source": [
    "def mb_numerical_delta(S, K, T, r, v, option='call'):\n",
    "    dS = 0.01 * S\n",
    "    option_plus = mb_black_scholes(S + dS, K, T, r, v, option)\n",
    "    option_minus = mb_black_scholes(S - dS, K, T, r, v, option)\n",
    "    delta = (option_plus - option_minus) / (2 * dS)\n",
    "    return delta\n",
    "\n",
    "def mb_numerical_gamma(S, K, T, r, v):\n",
    "    dS = 0.01 * S\n",
    "    delta_plus = mb_numerical_delta(S + dS, K, T, r, v)\n",
    "    delta_minus = mb_numerical_delta(S - dS, K, T, r, v)\n",
    "    gamma = (delta_plus - delta_minus) / (2 * dS)\n",
    "    return gamma\n",
    "\n",
    "def mb_numerical_vega(S, K, T, r, v):\n",
    "    dv = 0.01 * v\n",
    "    option_plus = mb_black_scholes(S, K, T, r, v + dv)\n",
    "    option_minus = mb_black_scholes(S, K, T, r, v - dv)\n",
    "    vega = (option_plus - option_minus) / (2 * dv)\n",
    "    return vega\n",
    "\n",
    "def mb_numerical_theta(S, K, T, r, v, option='call'):\n",
    "    dT = 0.01 * T\n",
    "    option_plus = mb_black_scholes(S, K, T + dT, r, v, option)\n",
    "    option_minus = mb_black_scholes(S, K, T - dT, r, v, option)\n",
    "    theta = (option_minus - option_plus) / dT  # time decay, theta is negative\n",
    "    return theta\n",
    "\n",
    "def mb_numerical_rho(S, K, T, r, v, option='call'):\n",
    "    dr = 0.01 * r\n",
    "    option_plus = mb_black_scholes(S, K, T, r + dr, v, option)\n",
    "    option_minus = mb_black_scholes(S, K, T, r - dr, v, option)\n",
    "    rho = (option_plus - option_minus) / (2 * dr)\n",
    "    return rho\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "30e183de-87ec-4344-9ee1-c7c43541684b",
   "metadata": {},
   "source": [
    "###### Greeks functions test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "b6223cf3-ef0b-462a-828f-ff814d1e5f17",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The analytical delta for a call is: 0.8037657315199467\n",
      "The numerical for a call is: 0.8037203528286747\n",
      "The analytical delta for a put is: -0.19623426848005332\n",
      "The numerical for a put is: -0.19627964717132937\n",
      "The analytical gamma is: 0.004518647805975139\n",
      "The numerical gamma is: 0.004519203443039656\n",
      "The analytical vega is: 48.43425617029602\n",
      "The numerical vega is: 48.43326173641824\n",
      "The analytical theta for a call is: -13.25709190333394\n",
      "The numerical for a call is: -26.51432269294247\n",
      "The analytical theta for a put is: -6.360678575703764\n",
      "The numerical for a put is: -12.721495462977828\n",
      "The analytical rho for a call is: 95.62194147064277\n",
      "The numerical for a call is: 95.62192560100868\n",
      "The analytical rho for a put is: -42.30632508196078\n",
      "The numerical for a put is: -42.30634669863775\n"
     ]
    }
   ],
   "source": [
    "# delta\n",
    "calladelta = mb_bs_delta(175, 145, 1, 0.05, 0.35, option = 'call')\n",
    "callndelta = mb_numerical_delta(175, 145, 1, 0.05, 0.35, option = 'call')\n",
    "putadelta = mb_bs_delta(175, 145, 1, 0.05, 0.35, option = 'put')\n",
    "putndelta = mb_numerical_delta(175, 145, 1, 0.05, 0.35, option = 'put')\n",
    "print(f\"The analytical delta for a call is: {calladelta}\")\n",
    "print(f\"The numerical for a call is: {callndelta}\")\n",
    "print(f\"The analytical delta for a put is: {putadelta}\")\n",
    "print(f\"The numerical for a put is: {putndelta}\")\n",
    "# Gamma\n",
    "agamma = mb_bs_gamma(175, 145, 1, 0.05, 0.35)\n",
    "ngamma = mb_numerical_gamma(175, 145, 1, 0.05, 0.35)\n",
    "print(f\"The analytical gamma is: {agamma}\")\n",
    "print(f\"The numerical gamma is: {ngamma}\")\n",
    "# Vega\n",
    "avega = mb_bs_vega(175, 145, 1, 0.05, 0.35)\n",
    "nvega = mb_numerical_vega(175, 145, 1, 0.05, 0.35)\n",
    "print(f\"The analytical vega is: {avega}\")\n",
    "print(f\"The numerical vega is: {nvega}\")\n",
    "# Theta\n",
    "callatheta = mb_bs_theta(175, 145, 1, 0.05, 0.35, option = 'call')\n",
    "callntheta = mb_numerical_theta(175, 145, 1, 0.05, 0.35, option = 'call')\n",
    "putatheta = mb_bs_theta(175, 145, 1, 0.05, 0.35, option = 'put')\n",
    "putntheta = mb_numerical_theta(175, 145, 1, 0.05, 0.35, option = 'put')\n",
    "print(f\"The analytical theta for a call is: {callatheta}\")\n",
    "print(f\"The numerical for a call is: {callntheta}\")\n",
    "print(f\"The analytical theta for a put is: {putatheta}\")\n",
    "print(f\"The numerical for a put is: {putntheta}\")\n",
    "# Rho\n",
    "callarho = mb_bs_rho(175, 145, 1, 0.05, 0.35, option = 'call')\n",
    "callnrho = mb_numerical_rho(175, 145, 1, 0.05, 0.35, option = 'call')\n",
    "putarho = mb_bs_rho(175, 145, 1, 0.05, 0.35, option = 'put')\n",
    "putnrho = mb_numerical_rho(175, 145, 1, 0.05, 0.35, option = 'put')\n",
    "print(f\"The analytical rho for a call is: {callarho}\")\n",
    "print(f\"The numerical for a call is: {callnrho}\")\n",
    "print(f\"The analytical rho for a put is: {putarho}\")\n",
    "print(f\"The numerical for a put is: {putnrho}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "feba1c43-4771-4c13-8e08-d0cc68b8c5fe",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "63d1c9ae-fc98-4a3a-8b14-e9f1a36f1f7e",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8c351378-adbd-4553-a9e2-5b0971d7e058",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "aa22786f-9385-4740-9015-d2477f777906",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8872f1c4-f0b7-41c8-9991-d9ae51e5538f",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
